package com.moran.controller;


import com.moran.domain.WeatherInfo;
import com.moran.util.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@Slf4j
@RestController
@RequestMapping("/v1.0.0")
public class ChatClientController {

    @Autowired
    private CommonUtil commonUtil;

    @Autowired
    private ChatMemory chatMemory;

    private final ChatClient chatClient;

    public ChatClientController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    /**
     * 当前用户输入后，返回文本类型的回答（上下文记忆）
     *
     * @return
     */
    @PostMapping("/chat")
    public String chat(@RequestParam("userInput")  String userInput) {
        return chatClient.prompt()
                .advisors(new SimpleLoggerAdvisor(), MessageChatMemoryAdvisor.builder(chatMemory).build())
                .user(userInput)
                .call()
                .content();
    }

    /**
     * 使用系统提示进行聊天。
     * @param userInput 用户输入的消息
     * @return AI 的回复
     */
    @PostMapping("/chatWithPromt")
    public String chatWithPromt(@RequestParam("userInput") String userInput) {
        return chatClient.prompt("你是一个java领域的专家。")
                .user(userInput)
                .call()
                .content();
    }

    /**
     * 使用流式提示和流式客户端与 DeepSeek 进行聊天。
     * @param userInput 用户输入的消息
     * @return 返回一个 Flux<String>，代表流式生成的回复片段
     * curl -X POST http://localhost:9167/v1.0.0/chatWithStream -d "userInput=spring简单原理"
     */
    @PostMapping("/chatWithStream")
    public Flux<String> chatWithStream(@RequestParam("userInput") String userInput) {
        // 创建提示并获取流式响应
        return chatClient.prompt("你是一个java领域的专家。").user(userInput).stream().content();
    }

    /**
     * 根据大模型返回消息封装实体对象
     */
    @PostMapping("/getWeatherInfoWithTemplate")
    public WeatherInfo getWeatherInfoWithTemplate(@RequestParam("city") String city) {
        String template = """
            你是一个专业的天气信息助手。
            请根据用户提供的城市名称，查询并返回详细的天气信息。
            你必须以严格的 JSON 格式返回，JSON 的结构必须完全匹配以下 Java Record 的定义：
            {weatherInfoSchema}

            城市: {city}
            """;

        // PromptTemplate 会自动将 weatherInfoSchema 替换为 WeatherInfo 类的 JSON Schema
        PromptTemplate promptTemplate = new PromptTemplate(template);
        promptTemplate.add("city", city);
        // ✅ 这行代码会自动生成 WeatherInfo 类的 JSON Schema
        promptTemplate.add("weatherInfoSchema", commonUtil.getJsonSchema(WeatherInfo.class));

        Prompt prompt = promptTemplate.create();

        return chatClient.prompt(prompt).call().entity(WeatherInfo.class);
    }

}
